package com.example.transaction.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.transaction.common.vo.Result;
import com.example.transaction.sys.entity.Address;
import com.example.transaction.sys.entity.Classfy;
import com.example.transaction.sys.entity.LoginLog;
import com.example.transaction.sys.entity.User;
import com.example.transaction.sys.mapper.AddressMapper;
import com.example.transaction.sys.service.IAddressService;
import com.example.transaction.sys.service.IClassfyService;
import com.example.transaction.sys.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zh
 * @since 2023-06-26
 */
@RestController
@RequestMapping("/sys/address")
public class AddressController {


    @Autowired
    private IAddressService addressService;

    @Autowired
    private IUserService userService;

    /**
     * 增加地址
     * @param address
     * @return
     */
    @CacheEvict(value = "address", allEntries = true)
    @PostMapping
    public Result<String> addAddress(@RequestBody Address address){
        try {
            addressService.save(address);
        }catch (Exception e){
            return Result.fail("地址新建失败");
        }
        return Result.success("地址添加成功");
    }

    /**
     * 根据地址id删除地址
     * @param addressid
     * @return
     */
    @CacheEvict(value = "address", allEntries = true)
    @DeleteMapping("/{addressid}")
    public Result<User>deleteAddressById(@PathVariable("addressid")Integer addressid){
        addressService.removeById(addressid);
        return Result.success("删除地址成功");
    }

    /**
     * 根据userID查到所有地址
     * @param userID
     * @return
     */
    @Cacheable(value = "address", key = "'userID'+#userID")
    @GetMapping("/userID")
    public Result<List<Address>> getaddressByuserID(@RequestParam(value = "userID",required = false)Integer userID) {
        List<Address> addressList = addressService.getUserInfoByUserID(userID);
        if (addressList != null && !addressList.isEmpty()) {
            return Result.success(addressList, "查询成功");
        } else {
            return Result.fail("该用户地址不存在");
        }
    }


    /**
     * 根据地址id查找地址
     * @param addressID
     * @return todo
     */
    @Cacheable(value = "address", key = "#addressID")
    @GetMapping("/{addressID}")
    public Result<Address> getaddressByAddressID(@PathVariable("addressID")Integer addressID) {
        Address address = addressService.getById(addressID);
        if (address != null) {
            return Result.success(address, "查询成功");
        } else {
            return Result.fail("该用户地址不存在");
        }
    }

    /**
     * 根据地址id更新地址
     * @param address
     * @return
     */
    @CacheEvict(value = "address", allEntries = true)
    @PutMapping("/updateByID")
    public Result<?>updateAddress(@RequestBody Address address){
        try {
            addressService.updateById(address);
        }catch (Exception e){
            return Result.fail("修改失败");
        }
        return Result.success("修改地址成功");
    }

    /**
     * 查询每个用户对应的所有地址，或者按条件查询
     * @param
     * @param
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Cacheable(value = "address", key = "'allusers'+#username+#pageNo+#pageSize")
    @GetMapping("/list")
    public Result<Map<String, Object>> getAddressList(@RequestParam(value = "userName", required = false) String username,
                                                       @RequestParam(value = "pageNo") Long pageNo,
                                                       @RequestParam(value = "pageSize") Long pageSize) {
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasLength(username)) {
            List<Integer> userIds = userService.getUserIdsByUsernameLike(username);
            if (!userIds.isEmpty()) {
                wrapper.in(Address::getUserID, userIds);
            } else {
                // 如果用户名不存在对应的用户ID，直接返回空结果
                Map<String, Object> data = new HashMap<>();
                data.put("total", 0);
                data.put("rows", Collections.emptyList());
                return Result.success(data);
            }
        }

        Page<Address> page = new Page<>(pageNo, pageSize);
        addressService.page(page, wrapper);

        List<Address> addressList = page.getRecords();

        // 使用 Map 来按照 userID 分组存储地址信息
        Map<Integer, List<Address>> addressMap = new HashMap<>();
        for (Address address : addressList) {
            int userID = address.getUserID();
            addressMap.computeIfAbsent(userID, k -> new ArrayList<>()).add(address);
        }

        List<Map<String, Object>> rows = new ArrayList<>();
        for (Map.Entry<Integer, List<Address>> entry : addressMap.entrySet()) {
            int userID = entry.getKey();
            List<Address> userAddressList = entry.getValue();

            // 将相同 userID 的地址信息合并为一条记录
            Map<String, Object> row = new HashMap<>();
            row.put("userID", userID);
            row.put("username", userService.getById(userID).getUsername()); // 添加用户名字段

            List<Map<String, Object>> addressDataList = new ArrayList<>();
            for (Address address : userAddressList) {
                Map<String, Object> addressData = new HashMap<>();
                addressData.put("addressID", address.getAddressID());
                addressData.put("recipienet", address.getRecipient());
                addressData.put("recipienetPhone", address.getRecipientPhone());
                addressData.put("addressDetail", address.getAddressDetail());
                addressDataList.add(addressData);
            }
            row.put("addresses", addressDataList);
            rows.add(row);
        }

        Map<String, Object> data = new HashMap<>();
        data.put("total", page.getTotal());
        data.put("rows", rows);

        return Result.success(data);
    }
}
